<template>
  <dy-view class="cell-box" :value="modelValue" @change="v => onChange(v)" ref="dyViewRef" :disabled="props.disabled">
    <button class="cell-box-flex clearbtn" :hover-class="props.onTap ? 'view-hover' : ''" :open-type="props.openType" @tap="$event => props.onTap?.call(null, $event)">
      <view v-if="props.label" class="cell-label">{{ props.label }}</view>
      <view class="grow stretch" v-if="slots.default">
        <slot v-bind="transmit"></slot>
      </view>
      <view class="grow stretch" v-else-if="isInput()">
        <input
          class="input"
          :disabled="props.disabled"
          :name="props.name"
          :maxlength="props.maxlength ?? 30"
          :value="modelValue"
          @input="e => onInput(e.detail.value)"
          @focus="focusValue = modelValue"
          @blur="onBlur"
          :placeholder="getPlaceholder()"
          v-bind="props.props"
          :type="props.type"
        />
      </view>
      <view class="grow stretch flex-end" v-else-if="props.type == 'switch'">
        <c-switch :disabled="props.disabled" :checked="modelValue" @change="e => onInput(e.detail.value)"></c-switch>
      </view>
      <view class="grow stretch" v-else :class="{ 'color-gray2': isEmpty() }">
        {{ isEmpty() ? getPlaceholder() : showValue() }}
      </view>
      <view class="cell-box-desc">
        <view v-if="props.num">{{ props.num }}</view>
        <view v-for="item in appends" :key="item" class="icon" @tap="emit('append', item)" :class="`icon-` + item"></view>
        <view
          v-if="props.arrow || isArrowDown()"
          class="icon"
          :class="{
            'icon-chevron-right': props.arrow != 'down' && !isArrowDown(),
            'icon-chevron-down': props.arrow == 'down' || isArrowDown()
          }"
        ></view>
      </view>
    </button>
    <view class="break" v-if="slots.break">
      <slot name="break" v-bind="transmit"></slot>
    </view>
    <view class="err-block" :class="{ 'err-show': !!errmsg }">
      {{ errmsg }}
    </view>
  </dy-view>
</template>
<script setup lang="jsx" title="CellBox">
import { Button, Input, Switch, Picker, View } from '@tarojs/components';
import { CCascader, CSwitch } from './';
import { computed, getCurrentInstance, shallowRef, ref } from 'vue';
import { anyType, useForm } from '@/hooks';

const props = defineProps({
  label: String,
  name: String,
  maxlength: [String, Number],
  openType: String,
  placeholder: String,
  required: Boolean,
  formatter: Function,
  rangeSplit: {
    type: String,
    default: ' / '
  },
  disabled: Boolean,
  append: [String, Array],
  onTap: Function,
  // 'right', 'down'
  arrow: [Boolean, String],
  num: Number,
  props: Object,
  // modelValue: {
  //   type: [Array, Object, String, Boolean],
  //   default: null
  // },
  // 'text', 'text','number','digit','idcard', 'password', 'switch', 'picker', 'date', 'time'
  type: {
    type: [String],
    default: 'none'
  }
});

const emit = defineEmits(['change', 'input']);
const focusValue = ref('');
const modelValue = defineModel('modelValue', anyType());

const { errors, changeError } = useForm();
const DyView = computed(() => (props.type == 'cascader' ? CCascader : isPicker() ? Picker : View));

const dyViewRef = shallowRef();

const errmsg = computed(() => {
  return errors.value[props.name];
});

const onInput = value => {
  changeError(props.name);
  modelValue.value = value;
  emit('input', value);
};
const onBlur = () => {
  if (modelValue.value != focusValue.value) {
    emit('change', modelValue.value);
  }
};
const onChange = e => {
  changeError(props.name);
  if (props.type == 'cascader') {
    modelValue.value = e;
  }
  emit('change', e);
};

const transmit = {
  clearMsg() {
    changeError(props.name);
  }
};

const showValue = () => {
  if (modelValue.value == null) {
    return modelValue.value;
  }
  if (props.type == 'cascader') {
    const newValues = dyViewRef.value?.getNames() ?? [];
    return newValues.map(a => a || '请选择').join(props.rangeSplit);
  }
  if (props.formatter) return modelValue.value;
  return modelValue.value;
};

const isEmpty = () => {
  return modelValue.value == null || modelValue.value.length == 0 || (props.type == 'cascader' && dyViewRef.value?.isEmpty());
};
const isInput = () => {
  return props.type == 'text' || props.type == 'password' || props.type == 'number' || props.type == 'digit' || props.type == 'idcard';
};

const isPicker = () => {
  return props.type == 'picker' || props.type == 'date' || props.type == 'time';
};

const isArrowDown = () => {
  return isPicker() || props.type == 'cascader';
};

const getPlaceholder = () => {
  if (props.placeholder != null) return props.placeholder;
  if (isInput()) {
    return '请输入' + props.label ?? '';
  }
  if (isArrowDown() || props.type == 'switch') {
    return '请选择' + props.label ?? '';
  }
  return '';
};

const appends = computed(() => {
  if (!props.append) return [];
  if (typeof props.append == 'string') {
    return [props.append];
  }
  return props.append;
});

const slots = defineSlots();
</script>
<style lang="scss">
.cell-box {
  position: relative;
  width: 100%;
  background-color: var(--color-caption);
  border-bottom: var(--onepx) solid var(--color-line);
  --height: 100px;
  .break {
    width: 100%;
    box-sizing: border-box;
    padding: 0px 30px 24px 30px;
  }
  .err-block {
    padding-left: 30px;
    font-size: 22px;
    color: var(--color-danger);
    height: 0px;
    line-height: 50px;
    transition: all 0.3s;
    left: 0;
    bottom: 0;
  }
  .err-show {
    height: 50px;
  }
  .cell-box-flex {
    display: flex;
    justify-content: space-between;
    box-sizing: border-box;
    padding: 0px 18px 0px 30px;
    font-size: 32px;
    height: var(--height);
    line-height: var(--height);
    color: rgba(0, 0, 0, 0.9);
  }
  &:last-child {
    border-bottom: 0px;
  }
  .cell-label {
    min-width: calc(28px * 5);
    font-size: 28px;
    box-sizing: content-box;
    padding-right: 20px;
  }
  .grow.stretch {
    align-self: stretch;
    height: 100%;
    overflow: hidden;
    font-size: 28px;

    .input {
      height: 100%;
      &[disabled] {
        color: var(--color-gray);
      }
      .input-placeholder {
        color: var(--color-gray2);
      }
    }
  }
  .cell-box-desc {
    display: flex;
    flex-shrink: 0;
    color: rgba(0, 0, 0, 0.4);
    align-items: center;
    font-size: 28px;
    .icon {
      font-size: 48px;
      color: #bbb;
    }
  }
}
</style>
